diff options
| author | bobzel <zzzman@gmail.com> | 2024-04-21 19:03:49 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-04-21 19:03:49 -0400 |
| commit | 939e18624af4252551f38c43335ee8ef0acd144c (patch) | |
| tree | d4e7a8dd4db05737ec1343ff8d80611537bde65b /src/client/views/collections/collectionFreeForm | |
| parent | 57d9c12d6b88d6814e468aca93b9bf809eabd9ce (diff) | |
more lint cleanup
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
4 files changed, 234 insertions, 142 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 29d835b28..65a529d62 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -4,7 +4,6 @@ import * as React from 'react'; import { Doc, DocListCast, FieldType, FieldResult } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { StrCast } from '../../../../fields/Types'; -import { DocumentManager } from '../../../util/DocumentManager'; import { LinkManager } from '../../../util/LinkManager'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton'; @@ -49,8 +48,8 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio setupStates = () => { this._originalbackground = StrCast(this._props.Document[DocData].backgroundColor); // state entry functions - const setBackground = (colour: string) => () => {this._props.Document[DocData].backgroundColor = colour;} // prettier-ignore - const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore + // const setBackground = (colour: string) => () => {this._props.Document[DocData].backgroundColor = colour;} // prettier-ignore + // const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore // arc transition trigger conditions const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined); const numDocs = () => this._props.childDocs().length; @@ -73,7 +72,6 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio let trail: number; - const trailView = () => DocumentManager.Instance.DocumentViews.find(view => view.Document === Doc.MyTrails); const presentationMode = () => Doc.ActivePresentation?.presentation_status; // set of states @@ -83,6 +81,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio docCreated: [() => numDocs(), () => { docX = firstDoc()?.x; docY = firstDoc()?.y; + // eslint-disable-next-line no-use-before-define return oneDoc; }], } @@ -93,18 +92,20 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio { // docCreated: [() => numDocs() > 1, () => multipleDocs], docDeleted: [() => numDocs() < 1, () => start], - docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => { + docMoved: [() => (docX && docX !== docNewX()) || (docY && docY !== docNewY()), () => { docX = firstDoc()?.x; docY = firstDoc()?.y; + // eslint-disable-next-line no-use-before-define return movedDoc; }], } ); // prettier-ignore const movedDoc = InfoState( - 'Great moves. Try creating a second document. You can see the list of supported document types by typing a colon (\":\")', + 'Great moves. Try creating a second document. You can see the list of supported document types by typing a colon (":")', { - docCreated: [() => numDocs() == 2, () => multipleDocs], + // eslint-disable-next-line no-use-before-define + docCreated: [() => numDocs() === 2, () => multipleDocs], docDeleted: [() => numDocs() < 1, () => start], }, 'dash-colon-menu.gif', @@ -114,6 +115,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio const multipleDocs = InfoState( 'Let\'s create a new link. Click the link icon on one of your documents.', { + // eslint-disable-next-line no-use-before-define linkStarted: [() => linkStart(), () => startedLink], docRemoved: [() => numDocs() < 2, () => oneDoc], }, @@ -124,6 +126,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio 'Now click the highlighted link icon on your other document.', { linkUnstart: [() => linkUnstart(), () => multipleDocs], + // eslint-disable-next-line no-use-before-define linkCreated: [() => numDocLinks(), () => madeLink], docRemoved: [() => numDocs() < 2, () => oneDoc], }, @@ -136,6 +139,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio linkCreated: [() => !numDocLinks(), () => multipleDocs], linkViewed: [() => linkMenuOpen(), () => { alert(numDocLinks() + " cheer for " + numDocLinks() + " link!"); + // eslint-disable-next-line no-use-before-define return viewedLink; }], }, @@ -147,10 +151,12 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio { linkDeleted: [() => !numDocLinks(), () => multipleDocs], docRemoved: [() => numDocs() < 2, () => oneDoc], - docCreated: [() => numDocs() == 3, () => { + docCreated: [() => numDocs() === 3, () => { trail = pin().length; + // eslint-disable-next-line no-use-before-define return presentDocs; }], + // eslint-disable-next-line no-use-before-define activePen: [() => activeTool() === InkTool.Pen, () => penMode], }, 'documentation.png', @@ -164,6 +170,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio () => pin().length > trail, () => { trail = pin().length; + // eslint-disable-next-line no-use-before-define return pinnedDoc1; }, ], @@ -186,11 +193,13 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio () => pin().length > trail, () => { trail = pin().length; + // eslint-disable-next-line no-use-before-define return pinnedDoc2; }, ], // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode], // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode], + // eslint-disable-next-line no-use-before-define autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode], docRemoved: [() => numDocs() < 3, () => viewedLink], }); @@ -200,11 +209,13 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio () => pin().length > trail, () => { trail = pin().length; + // eslint-disable-next-line no-use-before-define return pinnedDoc3; }, ], // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode], // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode], + // eslint-disable-next-line no-use-before-define autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode], docRemoved: [() => numDocs() < 3, () => viewedLink], }); @@ -219,6 +230,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio ], // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode], // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode], + // eslint-disable-next-line no-use-before-define autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode], docRemoved: [() => numDocs() < 3, () => viewedLink], }); @@ -236,15 +248,18 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio const manualPresentationMode = InfoState("You're in manual presentation mode.", { // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode], + // eslint-disable-next-line no-use-before-define autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode], docRemoved: [() => numDocs() < 3, () => viewedLink], - docCreated: [() => numDocs() == 4, () => completed], + // eslint-disable-next-line no-use-before-define + docCreated: [() => numDocs() === 4, () => completed], }); const autoPresentationMode = InfoState("You're in auto presentation mode.", { // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode], manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode], docRemoved: [() => numDocs() < 3, () => viewedLink], + // eslint-disable-next-line no-use-before-define docCreated: [() => numDocs() === 4, () => completed], }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index a0b96c75a..3970c6807 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ import { Doc, Field, FieldType, FieldResult } from '../../../../fields/Doc'; import { Id, ToString } from '../../../../fields/FieldSymbols'; import { ObjectField } from '../../../../fields/ObjectField'; @@ -48,7 +49,7 @@ export interface PoolData { export interface ViewDefResult { ele: JSX.Element; bounds?: ViewDefBounds; - inkMask?: number; //sort elements into either the mask layer (which has a mixedBlendMode appropriate for transparent masks), or the regular documents layer; -1 = no mask, 0 = mask layer but stroke is transparent (hidden, as in during a presentation when you want to smoothly animate it into being a mask), >0 = mask layer and not hidden + inkMask?: number; // sort elements into either the mask layer (which has a mixedBlendMode appropriate for transparent masks), or the regular documents layer; -1 = no mask, 0 = mask layer but stroke is transparent (hidden, as in during a presentation when you want to smoothly animate it into being a mask), >0 = mask layer and not hidden } function toLabel(target: FieldResult<FieldType>) { if (typeof target === 'number' || Number(target)) { @@ -84,9 +85,9 @@ interface PivotColumn { filters: string[]; } -export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { +export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) { const docMap = new Map<string, PoolData>(); - childPairs.forEach(({ layout, data }, i) => { + childPairs.forEach(({ layout, data }) => { docMap.set(layout[Id], { x: NumCast(layout.x), y: NumCast(layout.y), @@ -97,10 +98,15 @@ export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc replica: '', }); }); + // eslint-disable-next-line no-use-before-define return normalizeResults(panelDim, 12, docMap, poolData, viewDefsToJSX, [], 0, []); } -export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { +function toNumber(val: FieldResult<FieldType>) { + return val === undefined ? undefined : NumCast(val, Number(StrCast(val))); +} + +export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) { const docMap = new Map<string, PoolData>(); const burstDiam = [NumCast(pivotDoc._width), NumCast(pivotDoc._height)]; const burstScale = NumCast(pivotDoc._starburstDocScale, 1); @@ -132,7 +138,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do let nonNumbers = 0; const pivotFieldKey = toLabel(engineProps?.pivotField ?? pivotDoc._pivotField) || 'author'; - childPairs.map(pair => { + childPairs.forEach(pair => { const listValue = Cast(pair.layout[pivotFieldKey], listSpec('string'), null); const num = toNumber(pair.layout[pivotFieldKey]); @@ -184,11 +190,11 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do const textlen = Array.from(pivotColumnGroups.keys()) .map(c => getTextWidth(toLabel(c), desc)) .reduce((p, c) => Math.max(p, c), 0 as number); - const max_text = Math.min(Math.ceil(textlen / 120) * 28, panelDim[1] / 2); + const maxText = Math.min(Math.ceil(textlen / 120) * 28, panelDim[1] / 2); const maxInColumn = Array.from(pivotColumnGroups.values()).reduce((p, s) => Math.max(p, s.docs.length), 1); const colWidth = panelDim[0] / pivotColumnGroups.size; - const colHeight = panelDim[1] - max_text; + const colHeight = panelDim[1] - maxText; let numCols = 0; let bestArea = 0; let pivotAxisWidth = 0; @@ -212,7 +218,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do let x = 0; const sortedPivotKeys = pivotNumbers ? Array.from(pivotColumnGroups.keys()).sort((n1: FieldResult, n2: FieldResult) => toNumber(n1)! - toNumber(n2)!) : Array.from(pivotColumnGroups.keys()).sort(); sortedPivotKeys.forEach(key => { - const val = pivotColumnGroups.get(key)!; + const val = pivotColumnGroups.get(key); let y = 0; let xCount = 0; const text = toLabel(key); @@ -222,11 +228,11 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do x, y: pivotAxisWidth, width: pivotAxisWidth * expander * numCols, - height: max_text, + height: maxText, fontSize, payload: val, }); - val.docs.forEach((doc, i) => { + val?.docs.forEach((doc, i) => { const layoutDoc = Doc.Layout(doc); let wid = pivotAxisWidth; let hgt = pivotAxisWidth / (Doc.NativeAspect(layoutDoc) || 1); @@ -262,14 +268,11 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do payload: pivotColumnGroups.get(key)!.filters, })); groupNames.push(...dividers); - return normalizeResults(panelDim, max_text, docMap, poolData, viewDefsToJSX, groupNames, 0, []); -} - -function toNumber(val: FieldResult<FieldType>) { - return val === undefined ? undefined : NumCast(val, Number(StrCast(val))); + // eslint-disable-next-line no-use-before-define + return normalizeResults(panelDim, maxText, docMap, poolData, viewDefsToJSX, groupNames, 0, []); } -export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps?: any) { +export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps?: any */) { const fieldKey = 'data'; const pivotDateGroups = new Map<number, Doc[]>(); const docMap = new Map<string, PoolData>(); @@ -340,6 +343,7 @@ export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc: if (!stack && (curTime === undefined || Math.abs(x - (curTime - minTime) * scaling) > pivotAxisWidth)) { groupNames.push({ type: 'text', text: toLabel(key), x: x, y: stack * 25, height: fontHeight, fontSize, payload: undefined }); } + // eslint-disable-next-line no-use-before-define layoutDocsAtTime(keyDocs, key); }); if (sortedKeys.length && curTime !== undefined && curTime > sortedKeys[sortedKeys.length - 1]) { @@ -404,7 +408,7 @@ function normalizeResults( Array.from(docMap.entries()) .filter(ele => ele[1].pair) - .map(ele => { + .forEach(ele => { const newPosRaw = ele[1]; if (newPosRaw) { const newPos: PoolData = { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a70713429..d9c988d54 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/jsx-props-no-spreading */ /* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable jsx-a11y/no-static-element-interactions */ import { Bezier } from 'bezier-js'; @@ -22,7 +23,6 @@ import { TraceMobx } from '../../../../fields/util'; import { Gestures, PointData } from '../../../../pen-gestures/GestureTypes'; import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; import { aggregateBounds, emptyFunction, intersectRect, Utils } from '../../../../Utils'; -import { CognitiveServices } from '../../../cognitive_services/CognitiveServices'; import { Docs, DocUtils } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { DocumentManager } from '../../../util/DocumentManager'; @@ -48,6 +48,7 @@ import { DocumentView, OpenWhere } from '../../nodes/DocumentView'; import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { PresBox } from '../../nodes/trails/PresBox'; +// eslint-disable-next-line import/extensions import { CreateImage } from '../../nodes/WebBoxRenderer'; import { StyleProp } from '../../StyleProvider'; import { CollectionSubView } from '../CollectionSubView'; @@ -76,7 +77,7 @@ export interface collectionFreeformViewProps { @observer export class CollectionFreeFormView extends CollectionSubView<Partial<collectionFreeformViewProps>>() { public get displayName() { - return 'CollectionFreeFormView(' + this.Document.title?.toString() + ')'; + return 'CollectionFreeFormView(' + (this.Document.title?.toString() ?? '') + ')'; } // this makes mobx trace() statements more descriptive @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, ''); @@ -94,8 +95,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection super(props); makeObservable(this); } - @observable - public static ShowPresPaths = false; private _panZoomTransitionTimer: any; private _lastX: number = 0; @@ -238,7 +237,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } }; @observable _keyframeEditing = false; - @action setKeyFrameEditing = (set: boolean) => (this._keyframeEditing = set); + @action setKeyFrameEditing = (set: boolean) => { + this._keyframeEditing = set; + }; getKeyFrameEditing = () => this._keyframeEditing; onBrowseClickHandler = () => this._props.onBrowseClickScript?.() || ScriptCast(this.layoutDoc.onBrowseClick); onChildClickHandler = () => this._props.childClickScript || ScriptCast(this.Document.onChildClick); @@ -256,7 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection // this search order, for example, allows icons of cropped images to find the panx/pany/zoom on the cropped image's data doc instead of the usual layout doc because the zoom/panX/panY define the cropped image panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1)); panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1)); - zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); //, NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1)); + zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1)); PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`); ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy(); getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout); @@ -272,7 +273,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection addDocument = (newBox: Doc | Doc[]) => { let retVal = false; if (newBox instanceof Doc) { - if ((retVal = this._props.addDocument?.(newBox) || false)) { + retVal = this._props.addDocument?.(newBox) || false; + if (retVal) { this.bringToFront(newBox); this.updateCluster(newBox); } @@ -282,15 +284,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } if (retVal) { const newBoxes = newBox instanceof Doc ? [newBox] : newBox; - for (const newBox of newBoxes) { - if (newBox.activeFrame !== undefined) { - const vals = CollectionFreeFormDocumentView.animFields.map(field => newBox[field.key]); - CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[`${field.key}_indexed`]); - CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[field.key]); - delete newBox.activeFrame; - CollectionFreeFormDocumentView.animFields.forEach((field, i) => field.key !== 'opacity' && (newBox[field.key] = vals[i])); + newBoxes.forEach(box => { + if (box.activeFrame !== undefined) { + const vals = CollectionFreeFormDocumentView.animFields.map(field => box[field.key]); + CollectionFreeFormDocumentView.animFields.forEach(field => delete box[`${field.key}_indexed`]); + CollectionFreeFormDocumentView.animFields.forEach(field => delete box[field.key]); + delete box.activeFrame; + CollectionFreeFormDocumentView.animFields.forEach((field, i) => { + field.key !== 'opacity' && (box[field.key] = vals[i]); + }); } - } + }); if (this.Document._currentFrame !== undefined && !this._props.isAnnotationOverlay) { CollectionFreeFormDocumentView.setupKeyframes(newBoxes, NumCast(this.Document._currentFrame), true); } @@ -313,14 +317,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection }; focus = (anchor: Doc, options: FocusViewOptions) => { - if (this._lightboxDoc) return; + if (this._lightboxDoc) return undefined; if (anchor === this.Document) { // if (options.willZoomCentered && options.zoomScale) { // this.fitContentOnce(); // options.didMove = true; // } } - if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor) && !this.childLayoutPairs.map(pair => pair.layout).includes(anchor)) return; + // prettier-ignore + if (anchor.type !== DocumentType.CONFIG && + !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor) && // + !this.childLayoutPairs.map(pair => pair.layout).includes(anchor)) { + return undefined; + } const xfToCollection = options?.docTransform ?? Transform.Identity(); const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined }; const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc); @@ -336,12 +345,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this.setPan(panX, panY, focusTime, true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow return focusTime; } + return undefined; }; getView = async (doc: Doc, options: FocusViewOptions): Promise<Opt<DocumentView>> => new Promise<Opt<DocumentView>>(res => { if (doc.hidden && this._lightboxDoc !== doc) options.didMove = !(doc.hidden = false); - if (doc === this.Document) return res(this.DocumentView?.()); + if (doc === this.Document) { + res(this.DocumentView?.()); + return; + } const findDoc = (finish: (dv: DocumentView) => void) => DocumentManager.Instance.AddViewRenderedCb(doc, dv => finish(dv)); findDoc(dv => res(dv)); }); @@ -357,7 +370,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection .map(pair => pair.layout) .slice() .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex)); - zsorted.forEach((doc, index) => (doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1)); + zsorted.forEach((doc, index) => { + doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1; + }); const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000)); const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)]; @@ -410,7 +425,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection let added = false; // do nothing if link is dropped into any freeform view parent of dragged document const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, x, y, title: 'dropped annotation' }); - added = this._props.addDocument?.(source) ? true : false; + added = !!this._props.addDocument?.(source); de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { link_relationship: 'annotated by:annotation of' }); // TODODO this is where in text links get passed if (de.complete.linkDocument) { de.complete.linkDocument.layout_isSvg = true; @@ -425,8 +440,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData); - else if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData); - else if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData); + if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData); + if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData); return false; }; @@ -487,8 +502,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } @action - updateClusters(_freeform_useClusters: boolean) { - this.Document._freeform_useClusters = _freeform_useClusters; + updateClusters(useClusters: boolean) { + this.Document._freeform_useClusters = useClusters; this._clusterSets.length = 0; this.childLayoutPairs.map(pair => pair.layout).map(c => this.updateCluster(c)); } @@ -498,12 +513,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const childLayouts = this.childLayoutPairs.map(pair => pair.layout); if (this.Document._freeform_useClusters) { const docFirst = docs[0]; - docs.map(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1))); + docs.forEach(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1))); const preferredInd = NumCast(docFirst.layout_cluster); - docs.map(doc => (doc.layout_cluster = -1)); + docs.forEach(doc => { + doc.layout_cluster = -1; + }); docs.map(doc => this._clusterSets.map((set, i) => - set.map(member => { + set.forEach(member => { if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) { docFirst.layout_cluster = i; } @@ -518,19 +535,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection ) { docFirst.layout_cluster = preferredInd; } - this._clusterSets.map((set, i) => { + this._clusterSets.forEach((set, i) => { if (docFirst.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) { docFirst.layout_cluster = i; } }); if (docFirst.layout_cluster === -1) { - docs.map(doc => { + docs.forEach(doc => { doc.layout_cluster = this._clusterSets.length; this._clusterSets.push([doc]); }); } else if (this._clusterSets.length) { for (let i = this._clusterSets.length; i <= NumCast(docFirst.layout_cluster); i++) !this._clusterSets[i] && this._clusterSets.push([]); - docs.map(doc => this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc)); + docs.forEach(doc => { + this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc); + }); } childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.layout_cluster === i) && this.updateCluster(child)); } @@ -573,17 +592,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection if (doc && this.childDocList?.includes(doc)) switch (property.split(':')[0]) { case StyleProp.BackgroundColor: - const cluster = NumCast(doc?.layout_cluster); - if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) { - if (this._clusterSets.length <= cluster) { - setTimeout(() => doc && this.updateCluster(doc)); - } else { - // choose a cluster color from a palette - const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)']; - styleProp = colors[cluster % colors.length]; - const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor); - // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document - set?.map(s => (styleProp = StrCast(s.backgroundColor))); + { + const cluster = NumCast(doc?.layout_cluster); + if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) { + if (this._clusterSets.length <= cluster) { + setTimeout(() => doc && this.updateCluster(doc)); + } else { + // choose a cluster color from a palette + const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)']; + styleProp = colors[cluster % colors.length]; + const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor); + // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document + set?.forEach(s => { + styleProp = StrCast(s.backgroundColor); + }); + } } } break; @@ -591,6 +614,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection if (doc && this.Document._currentFrame !== undefined) { return CollectionFreeFormDocumentView.getStringValues(doc, NumCast(this.Document._currentFrame))?.fillColor; } + break; + default: } return styleProp; }; @@ -626,9 +651,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection case InkTool.None: if (!(this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) { this._hitCluster = this.pickCluster(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY)); - setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1 ? true : false, false); + setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1, false); } break; + default: } } } @@ -639,13 +665,34 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @undoBatch onGesture = (e: Event, ge: GestureUtils.GestureEvent) => { switch (ge.gesture) { - default: + // case Gestures.Rectangle: + // { + // const strokes = this.getActiveDocuments() + // .filter(doc => doc.type === DocumentType.INK) + // .map(i => { + // const d = Cast(i.stroke, InkField); + // const x = NumCast(i.x) - Math.min(...(d?.inkData.map(pd => pd.X) ?? [0])); + // const y = NumCast(i.y) - Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0])); + // return !d ? [] : d.inkData.map(pd => ({ X: x + pd.X, Y: y + pd.Y })); + // }); + + // CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => {}); + // } + // break; + case Gestures.Text: + if (ge.text) { + const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y); + this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] })); + e.stopPropagation(); + } + break; case Gestures.Line: case Gestures.Circle: case Gestures.Rectangle: case Gestures.Triangle: case Gestures.Stroke: - const points = ge.points; + default: { + const { points } = ge; const B = this.screenToFreeformContentsXf.transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height); const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale; const inkDoc = Docs.Create.InkDocument( @@ -664,29 +711,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } this.addDocument(inkDoc); e.stopPropagation(); - break; - case Gestures.Rectangle: - const strokes = this.getActiveDocuments() - .filter(doc => doc.type === DocumentType.INK) - .map(i => { - const d = Cast(i.stroke, InkField); - const x = NumCast(i.x) - Math.min(...(d?.inkData.map(pd => pd.X) ?? [0])); - const y = NumCast(i.y) - Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0])); - return !d ? [] : d.inkData.map(pd => ({ X: x + pd.X, Y: y + pd.Y })); - }); - - CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => {}); - break; - case Gestures.Text: - if (ge.text) { - const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y); - this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] })); - e.stopPropagation(); - } + } } }; @action - onEraserUp = (e: PointerEvent): void => { + onEraserUp = (): void => { this._deleteList.forEach(ink => ink._props.removeDocument?.(ink.Document)); this._deleteList = []; this._batch?.end(); @@ -792,7 +821,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection return this.childDocs .map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) .filter(inkView => inkView?.ComponentView instanceof InkingStroke) - .map(inkView => ({ inkViewBounds: inkView!.getBounds, inkStroke: inkView!.ComponentView as InkingStroke, inkView: inkView! })) + .map(inkView => inkView!) + .map(inkView => ({ inkViewBounds: inkView.getBounds, inkStroke: inkView.ComponentView as InkingStroke, inkView })) .filter( ({ inkViewBounds }) => inkViewBounds && // bounding box of eraser segment and ink stroke overlap @@ -807,7 +837,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection // Convert from screen space to ink space for the intersection. const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint); const currPointInkSpace = inkStroke.ptFromScreen(currPoint); - for (var i = 0; i < inkData.length - 3; i += 4) { + for (let i = 0; i < inkData.length - 3; i += 4) { const rawIntersects = InkField.Segment(inkData, i).intersects({ // compute all unique intersections p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y }, @@ -833,16 +863,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => { const segments: Segment[] = []; - var segment: Segment = []; - var startSegmentT = 0; + let segment: Segment = []; + let startSegmentT = 0; const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData(); // This iterates through all segments of the curve and splits them where they intersect another curve. // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted) - for (var i = 0; i < inkData.length - 3; i += 4) { + for (let i = 0; i < inkData.length - 3; i += 4) { const inkSegment = InkField.Segment(inkData, i); // Getting all t-value intersections of the current curve with all other curves. const tVals = this.getInkIntersections(i, ink, inkSegment).sort(); if (tVals.length) { + // eslint-disable-next-line no-loop-func tVals.forEach((t, index) => { const docCurveTVal = t + Math.floor(i / 4); if (excludeT < startSegmentT || excludeT > docCurveTVal) { @@ -895,9 +926,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const { inkData: otherInkData } = otherInk?.inkScaledData() ?? { inkData: [] }; const otherScreenPts = otherInkData.map(point => otherInk.ptToScreen(point)); const otherCtrlPts = otherScreenPts.map(spt => (ink.ComponentView as InkingStroke).ptFromScreen(spt)); - for (var j = 0; j < otherCtrlPts.length - 3; j += 4) { + for (let j = 0; j < otherCtrlPts.length - 3; j += 4) { const neighboringSegment = i === j || i === j - 4 || i === j + 4; // Ensuring that the curve intersected by the eraser is not checked for further ink intersections. + // eslint-disable-next-line no-continue if (ink?.Document === otherInk.Document && neighboringSegment) continue; const otherCurve = new Bezier(otherCtrlPts.slice(j, j + 4).map(p => ({ x: p.X, y: p.Y }))); @@ -908,7 +940,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection if (apt.d !== undefined && apt.d < 1 && apt.t !== undefined && !tVals.includes(apt.t)) { tVals.push(apt.t); } - this.bintersects(curve, otherCurve).forEach((val: string | number, i: number) => { + this.bintersects(curve, otherCurve).forEach((val: string | number /* , i: number */) => { // Converting the Bezier.js Split type to a t-value number. const t = +val.toString().split('/')[0]; if (i % 2 === 0 && !tVals.includes(t)) tVals.push(t); // bcz: Hack! don't know why but intersection points are doubled from bezier.js (but not identical). @@ -971,8 +1003,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this.scrollPan({ deltaX: -deltaX * this.screenToFreeformContentsXf.Scale, deltaY: e.shiftKey ? 0 : -deltaY * this.screenToFreeformContentsXf.Scale }); break; } - default: + // eslint-disable-next-line no-fallthrough case freeformScrollMode.Zoom: + default: if ((e.ctrlKey || !scrollable) && this._props.isContentActive()) { this.zoom(e.clientX, e.clientY, Math.max(-1, Math.min(1, e.deltaY))); // if (!this._props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc? // e.preventDefault(); @@ -982,7 +1015,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection }; @action - setPan(panX: number, panY: number, panTime: number = 0, clamp: boolean = false) { + setPan(panXIn: number, panYIn: number, panTime: number = 0, clamp: boolean = false) { + let panX = panXIn; + let panY = panYIn; // this is the easiest way to do this -> will talk with Bob about using mobx to do this to remove this line of code. if (Doc.UserDoc()?.presentationMode === 'watching') ReplayMovements.Instance.pauseFromInteraction(); @@ -1034,11 +1069,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection scale * NumCast(this.dataDoc._panY_max, nativeHeight) + (!this._props.getScrollHeight?.() ? fitYscroll : 0); // when not zoomed, scrolling is handled via a scrollbar, not panning let newPanY = Math.max(minPanY, Math.min(maxPanY, panY)); - if (false && NumCast(this.layoutDoc.layout_scrollTop) && NumCast(this.layoutDoc._freeform_scale, minScale) !== minScale) { - } else if (fitYscroll > 2 && this.layoutDoc.layout_scrollTop === undefined && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) { - const maxPanY = minPanY + fitYscroll; - const relTop = (panY - minPanY) / (maxPanY - minPanY); - setTimeout(() => (this.layoutDoc.layout_scrollTop = relTop * maxScrollTop), 10); + if (fitYscroll > 2 && this.layoutDoc.layout_scrollTop === undefined && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) { + const maxPanScrollY = minPanY + fitYscroll; + const relTop = (panY - minPanY) / (maxPanScrollY - minPanY); + setTimeout(() => { + this.layoutDoc.layout_scrollTop = relTop * maxScrollTop; + }, 10); newPanY = minPanY; } !this.Document._verticalScroll && (this.Document[this.panXFieldKey] = this.isAnnotationOverlay ? newPanX : panX); @@ -1090,7 +1126,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this._panZoomTransition = transitionTime; this._panZoomTransitionTimer && clearTimeout(this._panZoomTransitionTimer); this._panZoomTransitionTimer = setTimeout( - action(() => (this._panZoomTransition = 0)), + action(() => { + this._panZoomTransition = 0; + }), transitionTime ); }; @@ -1173,6 +1211,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection e.stopPropagation?.(); return this.createTextDocCopy(fieldProps, !e.altKey && e.key !== 'Tab'); } + return undefined; }; @computed get childPointerEvents() { const engine = this._props.layoutEngine?.() || StrCast(this.Document._layoutEngine); @@ -1194,6 +1233,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const childData = entry.pair.data; return ( <CollectionFreeFormDocumentView + // eslint-disable-next-line react/jsx-props-no-spreading {...OmitKeys(entry, ['replica', 'pair']).omit} key={childLayout[Id] + (entry.replica || '')} Document={childLayout} @@ -1205,7 +1245,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection isGroupActive={this._props.isGroupActive} renderDepth={this._props.renderDepth + 1} hideDecorations={BoolCast(childLayout._layout_isSvg && childLayout.type === DocumentType.LINK)} - suppressSetHeight={this.layoutEngine ? true : false} + suppressSetHeight={!!this.layoutEngine} RenderCutoffProvider={this.renderCutoffProvider} CollectionFreeFormView={this} LayoutTemplate={childLayout.z ? undefined : this._props.childLayoutTemplate} @@ -1239,37 +1279,42 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection /> ); } - addDocTab = action((doc: Doc, where: OpenWhere) => { - if (this._props.isAnnotationOverlay) return this._props.addDocTab(doc, where); + addDocTab = action((docsIn: Doc | Doc[], where: OpenWhere) => { + const docs = docsIn instanceof Doc ? [docsIn] : docsIn; + if (this._props.isAnnotationOverlay) return this._props.addDocTab(docs, where); switch (where) { case OpenWhere.inParent: - return this._props.addDocument?.(doc) || false; - case OpenWhere.inParentFromScreen: - const docContext = DocCast((doc instanceof Doc ? doc : doc?.[0])?.embedContainer); + return this._props.addDocument?.(docs) || false; + case OpenWhere.inParentFromScreen: { + const docContext = DocCast(docs[0]?.embedContainer); return ( (this.addDocument?.( - (doc instanceof Doc ? [doc] : doc).map(doc => { - const pt = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y)); - doc.x = pt[0]; - doc.y = pt[1]; + (docs instanceof Doc ? [docs] : docs).map(doc => { + [doc.x, doc.y] = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y)); return doc; }) ) && (!docContext || this._props.removeDocument?.(docContext))) || false ); + } case undefined: case OpenWhere.lightbox: - if (this.layoutDoc._isLightbox) { - this._lightboxDoc = doc; - return true; - } - if (doc === this.Document || this.childDocList?.includes(doc) || this.childLayoutPairs.map(pair => pair.layout)?.includes(doc)) { - if (doc.hidden) doc.hidden = false; - return true; + { + const firstDoc = docs[0]; + if (this.layoutDoc._isLightbox) { + this._lightboxDoc = firstDoc; + return true; + } + if (firstDoc === this.Document || this.childDocList?.includes(firstDoc) || this.childLayoutPairs.map(pair => pair.layout)?.includes(firstDoc)) { + if (firstDoc.hidden) firstDoc.hidden = false; + return true; + } } + break; + default: } - return this._props.addDocTab(doc, where); + return this._props.addDocTab(docs, where); }); @observable _lightboxDoc: Opt<Doc> = undefined; @@ -1314,9 +1359,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection e.stopPropagation(); }; - viewDefsToJSX = (views: ViewDefBounds[]) => { - return !Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!); - }; + viewDefsToJSX = (views: ViewDefBounds[]) => (!Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!)); viewDefToJSX(viewDef: ViewDefBounds): Opt<ViewDefResult> { const { x, y, z } = viewDef; @@ -1337,7 +1380,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection ), bounds: viewDef, }; - } else if (viewDef.type === 'div') { + } + if (viewDef.type === 'div') { return [x, y].some(val => val === undefined) ? undefined : { @@ -1353,9 +1397,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection bounds: viewDef, }; } + return undefined; } renderCutoffProvider = computedFn( + // eslint-disable-next-line prefer-arrow-callback function renderCutoffProvider(this: any, doc: Doc) { return this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + ''); }.bind(this) @@ -1369,7 +1415,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } doFreeformLayout(poolData: Map<string, PoolData>) { - this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair))); + this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair))); return [] as ViewDefResult[]; } @@ -1385,6 +1431,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection case computeTimelineLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) }; case computePivotLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) }; case computeStarburstLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeStarburstLayout) }; + default: } return { newPool, computedElementData: this.doFreeformLayout(newPool) }; } @@ -1469,7 +1516,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this._disposers.pointerevents = reaction( () => this.childPointerEvents, - pointerevents => (this._childPointerEvents = pointerevents as any), + pointerevents => { + this._childPointerEvents = pointerevents as any; + }, { fireImmediately: true } ); @@ -1643,7 +1692,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } }; - onContextMenu = (e: React.MouseEvent) => { + onContextMenu = () => { if (this._props.isAnnotationOverlay || !ContextMenu.Instance) return; const appearance = ContextMenu.Instance.findByDescription('Appearance...'); @@ -1654,7 +1703,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection !appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' }); return; } - !Doc.noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: 'Reset default note style', event: () => (Doc.UserDoc().defaultTextLayout = undefined), icon: 'eye' }); + !Doc.noviceMode && + Doc.UserDoc().defaultTextLayout && + appearanceItems.push({ + description: 'Reset default note style', + event: () => { + Doc.UserDoc().defaultTextLayout = undefined; + }, + icon: 'eye', + }); appearanceItems.push({ description: `Pin View`, event: () => this._props.pinToPres(this.Document, { pinViewport: MarqueeView.CurViewBounds(this.dataDoc, this._props.PanelWidth(), this._props.PanelHeight()) }), icon: 'map-pin' }); !Doc.noviceMode && appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: 'compress-arrows-alt' }); this._props.renderDepth && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' }); @@ -1669,8 +1726,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const optionItems = options && 'subitems' in options ? options.subitems : []; !this._props.isAnnotationOverlay && !Doc.noviceMode && - optionItems.push({ description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline', event: action(() => (this._showAnimTimeline = !this._showAnimTimeline)), icon: 'eye' }); - this._props.renderDepth && optionItems.push({ description: 'Use Background Color as Default', event: () => (Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor)), icon: 'palette' }); + optionItems.push({ + description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline', + event: action(() => { + this._showAnimTimeline = !this._showAnimTimeline; + }), + icon: 'eye', + }); + this._props.renderDepth && + optionItems.push({ + description: 'Use Background Color as Default', + event: () => { + Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor); + }, + icon: 'palette', + }); this._props.renderDepth && optionItems.push({ description: 'Fit Content Once', event: this.fitContentOnce, icon: 'object-group' }); if (!Doc.noviceMode) { optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? 'Freeze' : 'Unfreeze') + ' Aspect', event: this.toggleNativeDimensions, icon: 'snowflake' }); @@ -1750,7 +1820,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection ); } - showPresPaths = () => CollectionFreeFormView.ShowPresPaths; + showPresPaths = () => SnappingManager.ShowPresPaths; brushedView = () => this._brushedView; gridColor = () => DashColor(lightOrDark(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor))) @@ -1908,7 +1978,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection ) : ( <> {this._firstRender ? this.placeholder : this.marqueeView} - {this._props.noOverlay ? null : <CollectionFreeFormOverlayView elements={this.elementFunc} />} + { + // eslint-disable-next-line no-use-before-define + this._props.noOverlay ? null : <CollectionFreeFormOverlayView elements={this.elementFunc} /> + } {!this.GroupChildDrag ? null : <div className="collectionFreeForm-groupDropper" />} </> )} @@ -1920,7 +1993,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @observer class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { render() { - // eslint-disable-next-line react/destructuring-assignment return this.props.elements().filter(ele => ele.bounds?.z).map(ele => ele.ele); // prettier-ignore } } @@ -1959,6 +2031,7 @@ ScriptingGlobals.add(function curKeyFrame(readOnly: boolean) { const selView = SelectionManager.Views; if (readOnly) return selView[0].ComponentView?.getKeyFrameEditing?.() ? Colors.MEDIUM_BLUE : 'transparent'; runInAction(() => selView[0].ComponentView?.setKeyFrameEditing?.(!selView[0].ComponentView?.getKeyFrameEditing?.())); + return undefined; }); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function pinWithView(pinContent: boolean) { @@ -1989,7 +2062,7 @@ ScriptingGlobals.add(function datavizFromSchema() { if (!view.layoutDoc.schema_columnKeys) { view.layoutDoc.schema_columnKeys = new List<string>(['title', 'type', 'author', 'author_date']); } - const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text'); + const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key !== 'text'); if (!keys) return; const children = DocListCast(view.Document[Doc.LayoutFieldKey(view.Document)]); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b03e435ce..2f9cc49e0 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -196,7 +196,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps const eachCell = ns.join('\t').split('\t'); let eachRow = []; for (let i = 1; i < eachCell.length; i++) { - eachRow.push(eachCell[i].replace(/\,/g, '')); + eachRow.push(eachCell[i].replace(/,/g, '')); if (i % headers.length === 0) { csvRows.push(eachRow); eachRow = []; @@ -377,7 +377,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps }); @undoBatch - pileup = action((e: KeyboardEvent | React.PointerEvent | undefined) => { + pileup = action(() => { const selected = this.marqueeSelect(false); SelectionManager.DeselectAll(); selected.forEach(d => this._props.removeDocument?.(d)); @@ -485,7 +485,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps }); @undoBatch - summary = action((e: KeyboardEvent | React.PointerEvent | undefined) => { + summary = action(() => { const selected = this.marqueeSelect(false).map(d => { this._props.removeDocument?.(d); d.x = NumCast(d.x) - this.Bounds.left; @@ -530,8 +530,8 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps (e as any).propagationIsStopped = true; if (e.key === 'g') this.collection(e, true); if (e.key === 'c' || e.key === 't') this.collection(e); - if (e.key === 's' || e.key === 'S') this.summary(e); - if (e.key === 'p') this.pileup(e); + if (e.key === 's' || e.key === 'S') this.summary(); + if (e.key === 'p') this.pileup(); this.cleanupInteractions(false); } if (e.key === 'r' || e.key === ' ') { |
